package com.zenithmind.library.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zenithmind.library.pojo.domain.BorrowRecord;
import com.zenithmind.library.pojo.query.BorrowRecordQuery;
import com.zenithmind.library.pojo.vo.BorrowRecordVO;
import com.zenithmind.library.pojo.vo.BorrowStatisticsVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDate;
import java.util.List;

/**
 * 借阅记录Mapper接口
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Mapper
public interface BorrowRecordMapper extends BaseMapper<BorrowRecord> {

    /**
     * 分页查询借阅记录
     * 
     * @param page 分页参数
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BorrowRecordVO> selectBorrowRecordPage(Page<BorrowRecordVO> page, @Param("query") BorrowRecordQuery query);

    /**
     * 根据用户ID查询借阅记录
     * 
     * @param page 分页参数
     * @param userId 用户ID
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BorrowRecordVO> selectBorrowRecordsByUser(Page<BorrowRecordVO> page, 
                                                   @Param("userId") String userId, 
                                                   @Param("query") BorrowRecordQuery query);

    /**
     * 根据图书ID查询借阅记录
     * 
     * @param page 分页参数
     * @param bookId 图书ID
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BorrowRecordVO> selectBorrowRecordsByBook(Page<BorrowRecordVO> page, 
                                                   @Param("bookId") String bookId, 
                                                   @Param("query") BorrowRecordQuery query);

    /**
     * 获取用户当前借阅的图书
     * 
     * @param userId 用户ID
     * @return 借阅记录列表
     */
    List<BorrowRecordVO> selectCurrentBorrowsByUser(@Param("userId") String userId);

    /**
     * 获取逾期借阅记录
     * 
     * @param page 分页参数
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BorrowRecordVO> selectOverdueBorrows(Page<BorrowRecordVO> page, @Param("query") BorrowRecordQuery query);

    /**
     * 获取即将到期的借阅记录
     * 
     * @param page 分页参数
     * @param days 天数
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BorrowRecordVO> selectDueSoonBorrows(Page<BorrowRecordVO> page, 
                                              @Param("days") Integer days, 
                                              @Param("query") BorrowRecordQuery query);

    /**
     * 检查用户是否已借阅该图书
     * 
     * @param userId 用户ID
     * @param bookId 图书ID
     * @return 借阅记录数量
     */
    int countUserCurrentBorrowByBook(@Param("userId") String userId, @Param("bookId") String bookId);

    /**
     * 统计用户当前借阅数量
     * 
     * @param userId 用户ID
     * @return 借阅数量
     */
    int countUserCurrentBorrows(@Param("userId") String userId);

    /**
     * 统计用户逾期记录数量
     * 
     * @param userId 用户ID
     * @return 逾期记录数量
     */
    int countUserOverdueRecords(@Param("userId") String userId);

    /**
     * 统计用户未支付罚金总额
     * 
     * @param userId 用户ID
     * @return 罚金总额
     */
    Double sumUserUnpaidFines(@Param("userId") String userId);

    /**
     * 获取借阅统计信息
     * 
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 统计信息
     */
    BorrowStatisticsVO selectBorrowStatistics(@Param("startDate") LocalDate startDate, 
                                             @Param("endDate") LocalDate endDate);

    /**
     * 获取用户借阅统计
     * 
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 统计信息
     */
    BorrowStatisticsVO selectUserBorrowStatistics(@Param("userId") String userId, 
                                                 @Param("startDate") LocalDate startDate, 
                                                 @Param("endDate") LocalDate endDate);

    /**
     * 获取图书借阅统计
     * 
     * @param bookId 图书ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 统计信息
     */
    BorrowStatisticsVO selectBookBorrowStatistics(@Param("bookId") String bookId, 
                                                 @Param("startDate") LocalDate startDate, 
                                                 @Param("endDate") LocalDate endDate);

    /**
     * 更新借阅记录状态
     * 
     * @param id 记录ID
     * @param status 状态
     * @return 更新行数
     */
    int updateBorrowStatus(@Param("id") String id, @Param("status") Integer status);

    /**
     * 更新归还信息
     * 
     * @param id 记录ID
     * @param returnDate 归还日期
     * @param returnOperatorId 归还操作员ID
     * @param returnRemarks 归还备注
     * @return 更新行数
     */
    int updateReturnInfo(@Param("id") String id, 
                        @Param("returnDate") LocalDate returnDate, 
                        @Param("returnOperatorId") String returnOperatorId, 
                        @Param("returnRemarks") String returnRemarks);

    /**
     * 更新续借信息
     * 
     * @param id 记录ID
     * @param newDueDate 新的到期日期
     * @param renewalCount 续借次数
     * @return 更新行数
     */
    int updateRenewalInfo(@Param("id") String id, 
                         @Param("newDueDate") LocalDate newDueDate, 
                         @Param("renewalCount") Integer renewalCount);

    /**
     * 更新罚金信息
     * 
     * @param id 记录ID
     * @param fineAmount 罚金金额
     * @param overdueDays 逾期天数
     * @return 更新行数
     */
    int updateFineInfo(@Param("id") String id, 
                      @Param("fineAmount") Double fineAmount, 
                      @Param("overdueDays") Integer overdueDays);

    /**
     * 更新提醒信息
     * 
     * @param id 记录ID
     * @param reminderCount 提醒次数
     * @return 更新行数
     */
    int updateReminderInfo(@Param("id") String id, @Param("reminderCount") Integer reminderCount);

    /**
     * 批量更新逾期状态
     * 
     * @return 更新行数
     */
    int batchUpdateOverdueStatus();

    /**
     * 获取需要发送提醒的借阅记录
     * 
     * @param days 提前天数
     * @return 借阅记录列表
     */
    List<BorrowRecordVO> selectRecordsNeedReminder(@Param("days") Integer days);

    /**
     * 获取借阅趋势数据
     * 
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 趋势数据
     */
    List<BorrowStatisticsVO> selectBorrowTrend(@Param("startDate") LocalDate startDate, 
                                              @Param("endDate") LocalDate endDate);

    /**
     * 获取热门借阅图书排行
     * 
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param limit 限制数量
     * @return 图书排行列表
     */
    List<BorrowStatisticsVO> selectPopularBooksRanking(@Param("startDate") LocalDate startDate, 
                                                      @Param("endDate") LocalDate endDate, 
                                                      @Param("limit") Integer limit);

    /**
     * 获取活跃用户排行
     * 
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param limit 限制数量
     * @return 用户排行列表
     */
    List<BorrowStatisticsVO> selectActiveUsersRanking(@Param("startDate") LocalDate startDate, 
                                                     @Param("endDate") LocalDate endDate, 
                                                     @Param("limit") Integer limit);
}
